package com.powernode.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.powernode.clients.UserClient;
import com.powernode.domain.Prod;
import com.powernode.domain.ProdComm;
import com.powernode.domain.User;
import com.powernode.mapper.ProdCommMapper;
import com.powernode.mapper.ProdMapper;
import com.powernode.service.ProdCommService;
import com.powernode.vo.ProdCommView;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class ProdCommServiceImpl extends ServiceImpl<ProdCommMapper, ProdComm> implements ProdCommService{
    @Autowired
    private ProdCommMapper prodCommMapper;

    @Autowired
    private ProdMapper prodMapper;

    @Autowired
    private HttpServletRequest servletRequest;

    @Autowired
    private UserClient userClient;

    @Override
    @Transactional
    public void selectProdCommPage(Page<ProdComm> page, ProdComm prodComm) {
//        // 1. 根据商品名称查询商品id
//        List<Prod> prods = prodMapper.selectList(new LambdaQueryWrapper<Prod>()
//                .like(StrUtil.isNotEmpty(prodComm.getProdName()), Prod::getProdName, prodComm.getProdName()));
//
//        // 2. 处理ids
//        List<Long> ids = Collections.emptyList();
//        if (prods != null && prods.size() > 0) ids = prods.stream().map(Prod::getProdId).collect(Collectors.toList());

        //////////////////////////////SQL优化/////////////////////////////////////

//        // 1. 初始化ids为空集合
//        List<Long> ids = Collections.emptyList();
//
//        // 2. 如果有输入商品名查询条件则，ids要么为0 要么大于0
//        if (StrUtil.isNotEmpty(prodComm.getProdName())) {
//            ids = prodMapper.getIdsFromProdName(prodComm.getProdName());
//
//            // 3. 如果ids为0且有输入条件，则没有满足条件的，直接返回null
//            if (ids.size() == 0) return;
//        }
//
//        // 4. 接下来就剩没输入条件和输入了有ids的条件，就可正常使用条件分页查询了
//        prodCommMapper.selectPage(page, new LambdaQueryWrapper<ProdComm>()
//            .eq(ObjectUtil.isNotEmpty(prodComm.getStatus()), ProdComm::getStatus, prodComm.getStatus())
//            .in(StrUtil.isNotEmpty(prodComm.getProdName()), ProdComm::getProdId, ids)
//            .orderByDesc(ProdComm::getRecTime)
//        );
//
//        // 5. 处理page
//        List<ProdComm> records = page.getRecords();
//        records.forEach(item -> {
//            Prod prod = prodMapper.selectOne(new LambdaQueryWrapper<Prod>().eq(Prod::getProdId, item.getProdId()));
//            item.setProdName(prod.getProdName());
//        });


        /*
        1. 审核状态按照有值就查询的方式
        2. 商品名称可以认为和商品id一样
            没有商品名称则默认查询全部
            有商品名称
                先通过商品名称查询ids，根据ids是否空或是否大于0查询
        */

        // 1. 创建一个ids集合
        List<Long> ids = null;

        // 2. 如果商品名称不为空则查询，并填充ids
        if (StrUtil.isNotEmpty(prodComm.getProdName())) {
            // 根据商品名称查询商品
            List<Prod> prods = prodMapper.selectList(new LambdaQueryWrapper<Prod>().like(Prod::getProdName, prodComm.getProdName()));

            // 如果有商品则ids也有值
            if (prods.size() > 0) {
                ids = prods.stream().map(Prod::getProdId).collect(Collectors.toList());

             // 否则返回null
            } else {
                return ;
            }
        }

        // 3. 程序到这儿表明ids要么为null即商品名称为空，要么ids肯定有填充
        prodCommMapper.selectPage(page, new LambdaQueryWrapper<ProdComm>()
            .eq(ObjectUtil.isNotEmpty(prodComm.getStatus()), ProdComm::getStatus, prodComm.getStatus())
            .in(StrUtil.isNotEmpty(prodComm.getProdName()), ProdComm::getProdId, ids)
            .orderByDesc(ProdComm::getRecTime)
        );

        // 4. 处理page
        List<ProdComm> records = page.getRecords();
        records.forEach(item -> {
            Prod prod = prodMapper.selectOne(new LambdaQueryWrapper<Prod>().eq(Prod::getProdId, item.getProdId()));
            item.setProdName(prod.getProdName());
        });
    }

    @Override
    public ProdCommView selectProdCommView(Long prodId) {
        // 1. 评论总数
        Integer number = prodCommMapper.selectCount(new LambdaQueryWrapper<ProdComm>()
                .eq(ProdComm::getProdId, prodId)
                .eq(ProdComm::getStatus, 1)
        );

        // 2. 好评总数
        Integer positiveNumber = prodCommMapper.selectCount(new LambdaQueryWrapper<ProdComm>()
                .eq(ProdComm::getProdId, prodId)
                .eq(ProdComm::getEvaluate, 0)
                .eq(ProdComm::getStatus, 1)
        );


        // 3. 评论总数
        Integer secondaryNumber = prodCommMapper.selectCount(new LambdaQueryWrapper<ProdComm>()
                .eq(ProdComm::getProdId, prodId)
                .eq(ProdComm::getEvaluate, 1)
                .eq(ProdComm::getStatus, 1)
        );

        // 4. 评论总数
        Integer negativeNumber = prodCommMapper.selectCount(new LambdaQueryWrapper<ProdComm>()
                .eq(ProdComm::getProdId, prodId)
                .eq(ProdComm::getEvaluate, 2)
                .eq(ProdComm::getStatus, 1)
        );

        // 5. 有图评论
        Integer picNumber = prodCommMapper.selectCount(new LambdaQueryWrapper<ProdComm>()
                .eq(ProdComm::getProdId, prodId)
                .eq(ProdComm::getStatus, 1)
                .isNotNull(ProdComm::getPics)
        );

        // 6. 好评率
        BigDecimal rating = BigDecimal.ZERO;

        if (0 != number) {
            rating = new BigDecimal(positiveNumber)
                    .divide(new BigDecimal(number), 2, RoundingMode.HALF_DOWN)
                    .multiply(new BigDecimal(100));
        }


        return ProdCommView.builder()
                .positiveRating(rating)
                .number(number)
                .praiseNumber(positiveNumber)
                .secondaryNumber(secondaryNumber)
                .negativeNumber(negativeNumber)
                .picNumber(picNumber)
                .build();
    }

    @Override
    public void selectCommPage(Page<ProdComm> page, ProdComm prodComm) {
        // 1. 查询评论
        prodCommMapper.selectPage(page, new LambdaQueryWrapper<ProdComm>()
                .eq(ProdComm::getProdId, prodComm.getProdId())
                .eq(ProdComm::getStatus, 1)
                .eq(prodComm.getEvaluate() != null
                                && prodComm.getEvaluate() != -1 && prodComm.getEvaluate() != 3,
                        ProdComm::getEvaluate, prodComm.getEvaluate())
                .isNotNull(3 == prodComm.getEvaluate(), ProdComm::getPics)
                .orderByDesc(ProdComm::getRecTime)
        );

        // 2. 获取记录
        List<ProdComm> prodCommList = page.getRecords();
        if (prodCommList == null || prodCommList.size() == 0) return;

        // 3. 获取该商品评论用户的ids
        List<String> ids = prodCommList.stream()
                .map(ProdComm::getUserId)
                .collect(Collectors.toList());

        // 4. 远程调用获取ids所对应的用户信息
        List<User> userList = userClient.getUserInfoByIds(ids);

        // 5. 组装数据
        prodCommList.forEach(item -> {
            User targetUser = userList.stream().filter(user -> {
                 return user.getUserId().equals(item.getUserId());
            }).collect(Collectors.toList()).get(0);
            item.setPic(targetUser.getPic());

            StringBuilder sb = new StringBuilder(targetUser.getNickName());
            sb.replace(1, sb.length() - 1, "*");
            item.setNickName(sb.toString());
        });
    }


    @Override
    public boolean updateById(ProdComm entity) {
        // 1. 只有评论了说明已经回复了
        if (StrUtil.isNotEmpty(entity.getReplyContent())) {
            entity.setReplyTime(new Date());
            entity.setReplySts(1);
        }

        String ip = servletRequest.getRemoteHost();
        entity.setPostip(ip);

        return prodCommMapper.updateById(entity) > 0;
    }
}
